#include "logger.h" // 引入自定义的头文件

// --- 全局变量定义 ---
LogLevel g_log_level = LOG_INFO; // 默认级别为 INFO
FILE *g_log_file = NULL;         // 默认将在 log_init 中设置为 stderr 或文件
pthread_mutex_t g_log_mutex;     // 互斥锁

// 日志级别对应的字符串表示 (设为 static 使其只在当前文件可见)
static const char *level_strings[] = {
    "DEBUG", "INFO", "WARN", "ERROR", "FATAL"
};

int log_init(LogLevel level, const char *log_file_path) {
    g_log_level = level;

    if (pthread_mutex_init(&g_log_mutex, NULL) != 0) {
        perror("Failed to initialize log mutex");
        return -1;
    }

    if (log_file_path != NULL && strlen(log_file_path) > 0) {
        g_log_file = fopen(log_file_path, "a"); // 追加模式
        if (g_log_file == NULL) {
            perror("Failed to open log file");
            fprintf(stderr, "Logging will fall back to stderr for this session.\n");
            g_log_file = stderr; // 打开失败，则回退到 stderr
            // 注意：即使 fopen 失败，互斥锁也已初始化，需要在 log_close 中销毁
        }
    } else {
        g_log_file = stderr; // 如果没指定文件或路径为空，默认输出到标准错误
    }

    // 使用内部的 log_write 记录初始化信息，确保所有日志通过同一机制
    // 但要小心，此时 g_log_file 可能还未完全设定或 lock 未获取
    // 更安全的做法是直接 fprintf 到 stderr 或临时缓冲，或者在完全初始化后记录
    fprintf((g_log_file ? g_log_file : stderr), "[%s] [%s] [%lu] [%s:%d] - Log system initialized. Level: %s, Output: %s\n",
            "INIT_TIME_PLACEHOLDER", // 稍后log_write会填写真实时间
            "INFO",
            (unsigned long)pthread_self(),
            __FILE__, __LINE__,
            level_strings[g_log_level],
            (g_log_file == stderr) ? "stderr" : (log_file_path ? log_file_path : "stderr")
    );
    if (g_log_file != stderr) fflush(g_log_file); // 如果是文件，确保初始化消息写入


    return 0;
}

void log_close() {
    // 获取锁以安全地关闭文件和销毁互斥锁
    pthread_mutex_lock(&g_log_mutex);

    if (g_log_file != NULL && g_log_file != stderr) {
        fprintf(g_log_file, "[%s] [%s] [%lu] [%s:%d] - Closing log file.\n",
                "CLOSE_TIME_PLACEHOLDER", "INFO", (unsigned long)pthread_self(), __FILE__, __LINE__);
        fflush(g_log_file);
        fclose(g_log_file);
    }
    g_log_file = NULL; // 防止悬空指针

    pthread_mutex_unlock(&g_log_mutex);
    pthread_mutex_destroy(&g_log_mutex);
}

void log_write(LogLevel level, const char *file, int line, const char *fmt, ...) {
    if (level < g_log_level) {
        return;
    }

    time_t t = time(NULL);
    struct tm now_tm;
    localtime_r(&t, &now_tm); // 线程安全的 localtime

    char time_buf[64];
    strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &now_tm);

    pthread_mutex_lock(&g_log_mutex);

    // 检查 g_log_file 是否仍然有效 (例如，log_close 可能已被调用)
    // 或者在 log_init 失败时，g_log_file 可能为 NULL 或 stderr
    FILE* current_log_target = g_log_file ? g_log_file : stderr;


    fprintf(current_log_target, "[%s] [%s] [%lu] [%s:%d] - ",
            time_buf,
            level_strings[level],
            (unsigned long)pthread_self(),
            file, line);

    va_list args;
    va_start(args, fmt);
    vfprintf(current_log_target, fmt, args);
    va_end(args);

    fprintf(current_log_target, "\n");

    // if (level >= LOG_ERROR) { // 对于错误和致命错误，立即刷新
        fflush(current_log_target);
    // }

    pthread_mutex_unlock(&g_log_mutex);

    if (level == LOG_FATAL) {
        fprintf(stderr, "FATAL ERROR logged from [%s:%d]. Forcing exit.\n", file, line);
        // 在实际生产中，log_close 可能需要更复杂的信号处理或清理
        // 这里简化处理，确保互斥锁能被正确处理
        if (g_log_file != NULL && g_log_file != stderr) { // 如果日志文件打开了，尝试关闭
            fflush(g_log_file); // 确保所有缓冲内容写入文件
            fclose(g_log_file);
        }
        // FATAL 错误后，程序状态不可预测，通常直接退出
        // 互斥锁可能无法完美销毁，但程序即将终止
        exit(EXIT_FAILURE);
    }
}